<script lang="tsx">
  import { VxeModalInstance } from 'vxe-table';
  import { ModalPropsVxe } from '@/components/BasicVxeModal/useVxeModal';
  import { omit, set, get } from 'lodash-es';
  import { computed, getCurrentInstance, ref, unref, watch, watchEffect } from 'vue';
  import { BasicProps } from '@/components/BasicVxeModal/props';
  import { deepMerge } from '@/utils';

  export default defineComponent({
    inheritAttrs: false,
    props: BasicProps,
    emits: [
      'register',
      'update:modelValue',
      'show',
      'hide',
      'before-hide',
      'close',
      'confirm',
      'cancel',
      'zoom',
      'resize',
      'move',
    ],
    setup(props, { emit, attrs }) {
      const $Modal = ref<VxeModalInstance>();
      const propsRef: Ref<Partial<ModalPropsVxe>> = ref({});
      const openRef = ref(false);

      const setModalProps = async (props: Partial<ModalPropsVxe>) => {
        propsRef.value = deepMerge(unref(propsRef) || ({} as any), props);
        if (Reflect.has(props, 'modelValue')) {
          openRef.value = !!props.modelValue;
        }
        // Object.keys(props).map((key) => {
        //   set(propsRef.value, key, props[key]);
        // });
      };
      const setModalPropField = async (prop: string, value: any) => {
        if (prop === 'modelValue') {
          openRef.value = !!value;
        }
        set(propsRef.value, prop, value);
      };

      const getModalPropField = (prop: string): any => {
        return get(unref(propsRef), prop);
      };

      const getModalProps = (): ModalPropsVxe => {
        return unref(propsRef) as ModalPropsVxe;
      };

      // Custom title component: get title
      const getMergeProps = computed((): Recordable => {
        return {
          ...props,
          ...(unref(propsRef) as any),
        };
      });
      const getBindValue = computed((): Recordable => {
        const attr = {
          ...attrs,
          ...unref(getMergeProps),
          open: unref(openRef),
        };
        return attr;
        // return omit(attr, 'title');
      });

      watchEffect(() => {
        openRef.value = !!props.modelValue;
      });

      watch(
        () => unref(openRef),
        (v) => {
          emit('update:modelValue', v);
          instance && modalMethods.emitOpen?.(v, instance.uid);
        },
        {
          immediate: false,
        },
      );
      const modalMethods: any = {
        setModalProps,
        setModalPropField,
        getModalPropField,
        getModalProps,
      };
      [
        'dispatchEvent',
        'open',
        'close',
        'getBox',
        'getPosition',
        'setPosition',
        'isMinimized',
        'isMaximized',
        'zoom',
        'minimize',
        'maximize',
        'revert',
      ].map((key: string) => {
        if (!modalMethods[key]) {
          modalMethods[key] = async (...args) => {
            await nextTick();
            console.log($Modal.value?.[key], key, args);
            return ($Modal.value as VxeModalInstance)[key](...args);
          };
        }
      });
      // 注册
      const instance = getCurrentInstance();
      if (instance) {
        emit('register', modalMethods, instance.uid);
      }
      return {
        openRef,
        $Modal,
        getBindValue,
        omit,
      };
      // return () => (
      //   <vxe-modal
      //     ref={$Modal}
      //     v-model={openRef.value}
      //     {...omit(getBindValue.value, 'modelValue')}
      //     v-slots={slots}
      //   ></vxe-modal>
      // );
    },
  });
</script>
<template>
  <vxe-modal ref="$Modal" v-model="openRef" v-bind="omit(getBindValue, 'modelValue')">
    <template #[key]="slotData" v-for="key in Object.keys($slots)">
      <slot :name="key" v-bind="slotData ? { ...slotData } : {}"></slot>
    </template>
  </vxe-modal>
</template>

<style scoped lang="scss"></style>
